package com.lyj.calcdrink.calc;

import com.lyj.calcdrink.calc.conf.Timetable;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;

//上三天休息两天 上四天休息两天 上五天休息两天 那么请问 这三种人多久可以碰在一起喝一晚上酒
// 条件是 休息的最后一天不能喝酒 上班的最后一天可以喝酒
@Component
public class Drink {
    public void calculate(Timetable[] timetables, int circulationNum) {
        List<List<Integer>> coverTimetables = generateCycles(timetables);
        for (int i = 0; i < circulationNum ; i++) {
            int counter = calculateCounter(coverTimetables,i);
            showDate(counter);
        }
    }
    /**
     * 周期循环  返回全部为0的时间偏移量
     * @param coverTimetables
     * @param num
     * @return
     */
    public int calculateCounter(List<List<Integer>> coverTimetables, int num) {
        boolean flag = false;
        int counter = 0;
        int circulationNum = 0;
        // 开始循环
        while (!flag){
            counter++;
            List<Integer> daysFlagList = new ArrayList<>();
            for (List<Integer> coverTimetable : coverTimetables) {
                daysFlagList.add(calcDaysFlag(coverTimetable, counter));
            }
            // 判断是否为全0
            if (isDrinkDay(daysFlagList)) {
                flag = circulationNum >= num;
                circulationNum++;

            }
        }
        return counter;
    }

    /**
     * 计算今天是周期的第几天
     * @param cycleList
     * @param counter
     * @return
     */
    public int calcDaysFlag (List<Integer> cycleList, int counter) {
        int cycles = cycleList.size();
        return counter < cycles ? cycleList.get(counter): cycleList.get(counter % cycles);
    }

    /**
     * 计算当前周期数组是否都为0
     * @param daysFlagList
     * @return
     */
    public boolean isDrinkDay(List<Integer> daysFlagList) {
        for (Integer flag : daysFlagList) {
            if (flag != 0) {
                return false;
            }
        }
        return  true;
    }

    /**
     * 生成周期数组
     * @param timetables
     * @return
     */
    public List<List<Integer>> generateCycles(Timetable[] timetables) {
        // 利用今天作为时间偏移的标准值
        // 理解条件为: 能喝酒的日子为work的最后一天和rest的第一天
        // 计算原理 work为从1开始顺序增 rest为从0开始顺序减 那么最后一起出现0的时候 暨为所有人能喝酒的那天
        // 例子[1,2,3,4,5,0,-1]
        // 能喝酒的天数设定为0 后面判断是否都为0
        // 休息第一天减少1天 为上班的最后一天
        List<List<Integer>> coverTimetables = new ArrayList<>();
        // 转化数组
        Arrays.stream(timetables).forEach(v -> {
            List<Integer> tmp  = new ArrayList<>();
            // 添加工作日期  增加休息日期
            for (int i = 1; i <= v.getWorkDay() + v.getRestDay(); i++) {
                tmp.add((i >= v.getWorkDay() && i < v.getWorkDay() + v.getRestDay()) ? 0 : i);
            }
            // 需要考虑当前日期的偏移量 现阶段以工作第一天作为标定位置
            for (int k = 1; k < v.getOffset(); k++) {
                int tmpOffset = tmp.remove(0);
                tmp.add(tmpOffset);
            }

            coverTimetables.add(tmp);
        });

        return  coverTimetables;
    }


    /**
     * 展示日历时间
     * @param counter
     */
    public void showDate(int counter) {
        // counter 就是喝酒那天！
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, counter);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        System.out.print(" " + dateFormat.format(calendar.getTime())  + "\t \n");
    }
}
